package ioc

import (
	"context"
	"gitee.com/xiao_hange/go-admin-pkg/pkg/ginx/middleware/logger"
	"gitee.com/xiao_hange/go-admin-pkg/pkg/ginx/middleware/metric"
	"gitee.com/xiao_hange/go-admin-pkg/pkg/ginx/middleware/ratelimit"
	hlogger "gitee.com/xiao_hange/go-admin-pkg/pkg/logger"
	ratelimit2 "gitee.com/xiao_hange/go-admin-pkg/pkg/ratelimit"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"go-admin/server/internal/repository"
	"go-admin/server/internal/web"
	"go-admin/server/internal/web/middleware"
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
	"net/http"
	"strings"
	"time"
)

func InitGin(
	mdis []gin.HandlerFunc,
	mhld *web.MenuHander,
	rhld *web.RbacHandler,
	ahld *web.AdminHandler,
	shld *web.SettingHandler,
	fhld *web.FileHandler,
	phld *web.PackHandler,
	lhld *web.LogHandler,
) *gin.Engine {
	server := gin.Default()
	server.Use(mdis...)
	mhld.RegisterRoutes(server)
	rhld.RegisterRoutes(server)
	ahld.RegisterRoutes(server)
	shld.RegisterRoutes(server)
	fhld.RegisterRoutes(server)
	phld.RegisterRoutes(server)
	lhld.RegisterRoutes(server)
	(&web.ObservabilityHandler{}).RegisterRoutes(server)
	return server
}

func InitMiddleware(client redis.Cmdable, repo repository.AdminRepository, l hlogger.HttpLogger) []gin.HandlerFunc {
	return []gin.HandlerFunc{
		OptionsMiddleware,
		logger.NewBuilder(func(ctx context.Context, al *logger.AccessLog) {
			l.Info("HTTP请求", hlogger.String("Http", al.String()))
		}).AllowRespBody().AllowReqBody().Build(),
		cors.New(cors.Config{
			AllowMethods:     []string{"PUT", "DELETE", "POST", "GET"},
			AllowHeaders:     []string{"Authorization", "Content-Type", "Uuid"},
			ExposeHeaders:    []string{"X-Jwt-Token"},
			AllowCredentials: true,
			AllowOriginFunc: func(origin string) bool {
				if strings.HasPrefix(origin, "http://127.0.0.1") {
					return true
				}
				if strings.HasPrefix(origin, "http://localhost") {
					return true
				}
				return strings.Contains(origin, "正式域名")
			},
		}),
		//限流
		ratelimit.NewBuilder(ratelimit2.NewRedisSlideWindowLimiter(client, time.Second, 1000)).Build(),
		//登录验证
		middleware.NewLoginJWTMiddlewareBuilder(client).Build(),
		//权限验证
		middleware.NewPermissionVerificationMiddlewareBuilder(repo).Build(),
		//OpenTelemetry 中间件
		otelgin.Middleware("Go-Admin"),
		//Prometheus 统计 HTTP 请求
		(&metric.MiddlewareBuilder{
			Namespace:  "SunXQ",
			Subsystem:  "Go_Admin",
			Name:       "HTTP",
			Help:       "统计 GoAdmin 的 HTTP 请求",
			InstanceID: "My-Instance-ID",
		}).Build(),
	}
}
func OptionsMiddleware(c *gin.Context) {
	requestMethod := c.Request.Method
	if requestMethod == "OPTIONS" {
		c.AbortWithStatus(http.StatusNoContent)
	}
	c.Next()
}
